package com.zhiche.lisa.bms.service.pay.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zhiche.lisa.bms.dao.mapper.pay.PayApplyMapper;
import com.zhiche.lisa.bms.dao.model.bill.Bill;
import com.zhiche.lisa.bms.dao.model.bill.BillDetail;
import com.zhiche.lisa.bms.dao.model.fee.FeeAssessment;
import com.zhiche.lisa.bms.dao.model.fee.FeePayable;
import com.zhiche.lisa.bms.dao.model.fee.FeeReward;
import com.zhiche.lisa.bms.dao.model.pay.*;
import com.zhiche.lisa.bms.dao.model.prepay.PrepayBill;
import com.zhiche.lisa.bms.enums.ActivitiEnum;
import com.zhiche.lisa.bms.enums.FeePayableBaseEnum;
import com.zhiche.lisa.bms.enums.FleetAttributeEnum;
import com.zhiche.lisa.bms.pojo.dto.pay.PayApplyAssess;
import com.zhiche.lisa.bms.pojo.dto.pay.PayApplyToBmsBill;
import com.zhiche.lisa.bms.pojo.dto.util.*;
import com.zhiche.lisa.bms.pojo.vo.activiti.HistoryTask;
import com.zhiche.lisa.bms.pojo.vo.common.CommonVO;
import com.zhiche.lisa.bms.pojo.vo.fee.FeeAssessmentVO;
import com.zhiche.lisa.bms.pojo.vo.fee.FeeRewardVO;
import com.zhiche.lisa.bms.pojo.vo.pay.PayApplyCapitalVO;
import com.zhiche.lisa.bms.pojo.vo.pay.PayApplyObjVO;
import com.zhiche.lisa.bms.pojo.vo.pay.PayApplyVO;
import com.zhiche.lisa.bms.pojo.vo.prepay.SinglePrepayBill;
import com.zhiche.lisa.bms.service.activiti.ActivitiCommonService;
import com.zhiche.lisa.bms.service.arfund.ArFundService;
import com.zhiche.lisa.bms.service.bill.BillDetailService;
import com.zhiche.lisa.bms.service.bill.BillService;
import com.zhiche.lisa.bms.service.fee.FeeAssessmentService;
import com.zhiche.lisa.bms.service.fee.FeePayableService;
import com.zhiche.lisa.bms.service.fee.FeeRewardService;
import com.zhiche.lisa.bms.service.pay.*;
import com.zhiche.lisa.bms.service.prepay.PrepayBillService;
import com.zhiche.lisa.bms.service.utils.LspUtil;
import com.zhiche.lisa.bms.service.utils.OtmUtil;
import com.zhiche.lisa.bms.service.utils.PayApiUtil;
import com.zhiche.lisa.bms.service.utils.common.identityCodeUtil.CodeUtil;
import com.zhiche.lisa.core.supports.BaseException;
import com.zhiche.lisa.core.utils.Account.AccountUtil;
import com.zhiche.lisa.core.utils.Account.JwtAccountVO;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

/**
 * <p>
 * 支付申请单主表 服务实现类
 * </p>
 *
 * @author hongbo
 * @since 2018-09-27
 */
@Service
public class PayApplyServiceImpl extends ServiceImpl<PayApplyMapper, PayApply> implements PayApplyService {

    private static final Logger LOGGER = LoggerFactory.getLogger(PayApplyServiceImpl.class);

    @Autowired
    private CodeUtil codeUtil;
    @Autowired
    private LspUtil lspUtil;

    @Autowired
    private PayAffirmService payAffirmService;

    @Autowired
    private PayAffirmApplyService payAffirmApplyService;

    /**
     * 账单状态 0-新增 1-审核
     */
    private final Integer BILL_STATUS = 0;

    /**
     * 支付申请明细表-考核扣款
     */
    @Autowired
    private PayApplyDtlAsseService payApplyDtlAsseService;
    /**
     * 支付申请明细表-账单
     */
    @Autowired
    private PayApplyDtlBillService payApplyDtlBillService;
    /**
     * 支付申请明细表-其他扣款
     */
    @Autowired
    private PayApplyDtlFundService payApplyDtlFundService;
    /**
     * 支付申请明细表-预付账单
     */
    @Autowired
    private PayApplyDtlPrepayService payApplyDtlPrepayService;
    /**
     * 其他扣款
     */
    @Autowired
    private ArFundService arFundService;
    /**
     * 账单
     */
    @Autowired
    private BillService billService;

    /**
     * 账单明细
     */
    @Autowired
    private BillDetailService billDetailService;

    /**
     * 预付账单
     */
    @Autowired
    private PrepayBillService prepayBillService;
    /**
     * 考核奖惩
     */
    @Autowired
    private FeeAssessmentService feeAssessmentService;
    /**
     * 应付账款
     */
    @Autowired
    private FeePayableService feePayableService;

    /**
     * 审批流
     */
    @Autowired
    private ActivitiCommonService activitiCommonService;

    @Autowired
    private FeeRewardService feeRewardService;

    @Autowired
    private PayApiUtil payApiUtil;

    @Autowired
    private OtmUtil otmUtil;

    @Override
    public Page<PayApply> queryPayApplyPage(Page<PayApply> page) {
        EntityWrapper<PayApply> ew = this.queryCheck(page.getCondition());
        //清空page附加条件值
        page.setCondition(Maps.newHashMap());
        page.setRecords(baseMapper.selectPage(page, ew));
        return page;
    }

    @Override
    public List<PayApply> queryPayApplyList(Map<String, Object> condition) {
        EntityWrapper<PayApply> ew = this.queryCheck(condition);
        return baseMapper.selectList(ew);
    }

    /**
     * 根据id集合查询支付申请列表
     *
     * @param ids
     * @return
     */
    @Override
    public List<PayApply> queryPayApplyByIds(List<Long> ids) {
        EntityWrapper<PayApply> ew = new EntityWrapper<>();
        ew.in("id", ids);
        ew.orderBy("id desc");
        return this.selectList(ew);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PayApply insertPayApply(PayApplyVO payApplyVO) {
        Calendar instance = Calendar.getInstance();

        if (ObjectUtils.isEmpty(payApplyVO)) throw new BaseException("没有支付申请数据！");
        if (payApplyVO.getBillIDList().isEmpty()) throw new BaseException("获取不到支付申请的账单数据！");
        JwtAccountVO account = AccountUtil.getAccountInfoFromSecurityContext();
        if (ObjectUtils.isEmpty(account)) throw new BaseException("没有登录信息！");
        payApplyVO.setTenantId(Long.valueOf(account.getTenantId()));
        payApplyVO.setPayApplyCode(codeUtil.getPayApplyCode().getNextCode(null));
        payApplyVO.setBalance(payApplyVO.getBillSum());//余额默认为账单金额
        if (payApplyVO.getBalance() != null) {
            payApplyVO.setBalance(payApplyVO.getBalance().setScale(2, BigDecimal.ROUND_HALF_UP));
        }
        payApplyVO.setApplyDate(new Date());
        payApplyVO.setStatus(BILL_STATUS);
        if (payApplyVO.getPaymentSum() != null) {
            payApplyVO.setPaymentSum(payApplyVO.getPaymentSum().setScale(2, BigDecimal.ROUND_HALF_UP));
        }
        payApplyVO.setNoExecuteSum(payApplyVO.getPaymentSum());
        if (payApplyVO.getNoExecuteSum() != null) {
            payApplyVO.setNoExecuteSum(payApplyVO.getNoExecuteSum().setScale(2, BigDecimal.ROUND_HALF_UP));
        }
        payApplyVO.setExecuteSum(BigDecimal.ZERO);
        if (payApplyVO.getOilBaPaySum() == null) {
            payApplyVO.setOilBaPaySum(BigDecimal.ZERO);
        }
        if (payApplyVO.getOilErPaySum() == null) {
            payApplyVO.setOilErPaySum(payApplyVO.getOilBaPaySum());
        }
        if (payApplyVO.getOilAlPaySum() == null) {
            payApplyVO.setOilAlPaySum(payApplyVO.getOilBaPaySum().subtract(payApplyVO.getOilErPaySum()));
        }

        if (payApplyVO.getCashBaPaySum() == null) {
            payApplyVO.setCashBaPaySum(BigDecimal.ZERO);
        }
        if (payApplyVO.getCashErPaySum() == null) {
            payApplyVO.setCashErPaySum(payApplyVO.getCashBaPaySum());
        }
        if (payApplyVO.getCashAlPaySum() == null) {
            payApplyVO.setCashAlPaySum(payApplyVO.getCashBaPaySum().subtract(payApplyVO.getCashErPaySum()));
        }
        if (payApplyVO.getPremium() == null) {
            payApplyVO.setPremium(BigDecimal.ZERO);
        }

        if (payApplyVO.getShouldReceiptDateType() != null) {
            if (Objects.deepEquals(new Integer(1), payApplyVO.getShouldReceiptDateType())) {
                if ((instance.get(Calendar.MONTH) + 1) == 2) {
                    instance.set(Calendar.DAY_OF_MONTH, instance.getActualMaximum(Calendar.DAY_OF_MONTH));
                    payApplyVO.setShouldReceiptDate(instance.getTime());
                } else {
                    instance.set(Calendar.DAY_OF_MONTH, 30);
                    payApplyVO.setShouldReceiptDate(instance.getTime());
                }
            } else if (Objects.deepEquals(new Integer(2), payApplyVO.getShouldReceiptDateType())) {
                if ((instance.get(Calendar.MONTH) + 1) == 1) {
                    instance.add(Calendar.MONTH, 1);
                    instance.set(Calendar.DAY_OF_MONTH, instance.getActualMaximum(Calendar.DAY_OF_MONTH));
                    payApplyVO.setShouldReceiptDate(instance.getTime());
                } else {
                    instance.add(Calendar.MONTH, 1);
                    instance.set(Calendar.DAY_OF_MONTH, 30);
                    payApplyVO.setShouldReceiptDate(instance.getTime());
                }
            }
        }
        //新增支付申请数据-第一步
        this.insert(payApplyVO);
        //新增支付关系数据-第二步
        this.insertPayDetailed(payApplyVO);
        //计算付款金额-第三步
        this.calculationPayMoney(payApplyVO);
        return payApplyVO;
    }

    /**
     * 修改支付申请，对应的关系
     *
     * @param payApplyVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updatePayApplyToDetailed(PayApplyVO payApplyVO) {
        if (ObjectUtils.isEmpty(payApplyVO)) throw new BaseException("没有支付申请数据！");
        if (payApplyVO.getBillIDList().isEmpty()) throw new BaseException("获取不到支付申请的账单数据！");

        List<PayApplyDtlBill> payApplyDtlBills = payApplyDtlBillService.queryPayApplyDtlBillList(payApplyVO.getId());

        //支付申请明细表-账单
        if (!CollectionUtils.isEmpty(payApplyDtlBills)) {
            List<Long> billIds = new ArrayList<>();
            payApplyDtlBills.forEach(payApplyDtlBill -> {
                billIds.add(payApplyDtlBill.getBilId());
            });
            payApplyDtlBillService.deletePayApplyDtlBillList(payApplyVO.getId());
            billService.cleanLockBill(billIds);
        }

        //支付申请明细表-考核扣款
        updateRollBackAssceeList(payApplyVO.getId(), payApplyVO.getFeeAssessments());
        payApplyDtlAsseService.deletePayApplyDtlAsseList(payApplyVO.getId());
        //支付申请明细表-其他扣款
        updateRollBackOtherAsscee(payApplyVO.getId(), payApplyVO.getArfunds());
        payApplyDtlFundService.deletePayApplyDtlFundList(payApplyVO.getId());
        //支付申请明细表-预付账单
        payApplyDtlPrepayService.deletePayApplyDtlPrepayList(payApplyVO.getId());

        PayApply payApply = new PayApply();
        BeanUtils.copyProperties(payApplyVO, payApply);
        this.insertOrUpdate(payApply);
        //新增支付关系数据
        this.insertPayDetailed(payApplyVO);

        //计算付款金额
        this.calculationPayMoney(payApplyVO);
    }

    /**
     * 更新回退补贴已执行金额
     */
    private void updateRollBackOtherAsscee(Long payId, List<FeeRewardVO> feeRewardVOList) {
        if (payId != null) {
            List<PayApplyDtlFund> dtlFundList = payApplyDtlFundService.queryPayApplyDtlFundList(payId);
            if (!CollectionUtils.isEmpty(dtlFundList)) {
                List<FeeReward> rewardList = Lists.newArrayList();
                for (PayApplyDtlFund dtl : dtlFundList) {
                    if (dtl.getId() != null) {
                        for (FeeRewardVO feeRewardVO : feeRewardVOList) {
                            if (dtl.getBilId().equals(feeRewardVO.getId()) && feeRewardVO.getSingleWithHoldSum() == null) {
                                feeRewardVO.setSingleWithHoldSum(dtl.getArSum());
                                continue;
                            }
                        }
                        FeeReward feeReward = feeRewardService.selectById(dtl.getBilId());
                        if (feeReward != null) {
                            if (feeReward.getPerformSum() == null) {
                                feeReward.setPerformSum(BigDecimal.ZERO);
                            }
                            if (feeReward.getBalanceSum() == null) {
                                feeReward.setBalanceSum(BigDecimal.ZERO);
                            }
                            feeReward.setPerformSum(feeReward.getPerformSum().subtract(dtl.getArSum()));
                            feeReward.setBalanceSum(feeReward.getBalanceSum().add(dtl.getArSum()));
                            rewardList.add(feeReward);
                        }
                    }
                }
                if (!CollectionUtils.isEmpty(rewardList)) {
                    feeRewardService.updateBatchById(rewardList);
                }
            }
        }
    }

    /**
     * 更新考核单已执行金额
     */
    private void updateRollBackAssceeList(Long payId, List<FeeAssessmentVO> assessmentVOList) {
        if (payId != null) {
            List<PayApplyDtlAsse> payApplyDtlAsseList = payApplyDtlAsseService.queryPayApplyDtlAsseList(payId);
            if (!CollectionUtils.isEmpty(payApplyDtlAsseList)) {
                List<FeeAssessment> feeAssessmentList = Lists.newArrayList();
                for (PayApplyDtlAsse dtl : payApplyDtlAsseList) {
                    if (dtl.getId() != null) {
                        for (FeeAssessmentVO feeAssessmentVO : assessmentVOList) {
                            if (dtl.getBilId().equals(feeAssessmentVO.getId()) && feeAssessmentVO.getSingleAssesmentSum() == null) {
                                feeAssessmentVO.setSingleAssesmentSum(dtl.getArSum());
                                continue;
                            }
                        }
                        FeeAssessment feeAssessment = feeAssessmentService.selectById(dtl.getBilId());
                        if (feeAssessment != null) {
                            if (feeAssessment.getPerformSum() == null) {
                                feeAssessment.setPerformSum(BigDecimal.ZERO);
                            }
                            if (feeAssessment.getBalanceSum() == null) {
                                feeAssessment.setBalanceSum(BigDecimal.ZERO);
                            }
                            feeAssessment.setPerformSum(feeAssessment.getPerformSum().subtract(dtl.getArSum()));
                            feeAssessment.setBalanceSum(feeAssessment.getBalanceSum().add(dtl.getArSum()));
                            feeAssessmentList.add(feeAssessment);
                        }
                    }
                }
                if (!CollectionUtils.isEmpty(feeAssessmentList)) {
                    feeAssessmentService.updateBatchById(feeAssessmentList);
                }
            }
        }
    }

    private void insertPayDetailed(PayApplyVO payApplyVO) {
        Long id = payApplyVO.getId();
        //支付申请明细表-账单
        List<Long> billIDList = payApplyVO.getBillIDList();//账单主表id
        billIDList.forEach(billID -> {
            PayApplyDtlBill payApplyDtlBill = new PayApplyDtlBill();
            payApplyDtlBill.setHeadId(id);
            payApplyDtlBill.setBilId(billID);
            payApplyDtlBillService.insert(payApplyDtlBill);
        });
        billService.lockBill(billIDList);


        //支付申请明细表-其他扣款
        //List<ArFundVO> arfunds = payApplyVO.getArfunds();//其他扣款主表id
        //List<Long> arfundItemIds = new ArrayList<>();
        //if (!arfunds.isEmpty()) arfunds.forEach(arFundVO -> {
        //	ArFund arFund = arFundService.selectById(arFundVO.getId());
        //	if (arFund == null) throw new BaseException("指定其他扣款不存在");
        //	BeanUtils.copyProperties(arFund, arFundVO);
        //
        //	/*
        //	 获取金额数据
        //	 */
        //	BigDecimal sum = arFundVO.getSum();
        //	BigDecimal executeSum = arFundVO.getExecuteSum();
        //	BigDecimal balance = arFundVO.getBalance();
        //	BigDecimal singleWithHoldSum = arFundVO.getSingleWithHoldSum();
        //	/*
        //	 验证数据
        //	 */
        //	sum = (sum == null ? BigDecimal.ZERO : sum);
        //	executeSum = (executeSum == null ? BigDecimal.ZERO : executeSum);
        //	balance = (balance == null ? BigDecimal.ZERO : balance);
        //	singleWithHoldSum = (singleWithHoldSum == null ? BigDecimal.ZERO : singleWithHoldSum);
        //	if (balance.compareTo(singleWithHoldSum) < 0) {
        //		throw new BaseException("指定其他扣款剩余金额不足");
        //	}
        //	if (sum.compareTo(executeSum.add(balance)) < 0) {
        //		throw new BaseException("指定其他扣款已扣金额和剩余金额不符");
        //	}
        //	arFundVO.setExecuteSum(executeSum.add(singleWithHoldSum));
        //	arFundVO.setBalance(balance.subtract(singleWithHoldSum));
        //
        //	arfundItemIds.add(arFundVO.getId());
        //	PayApplyDtlFund payApplyDtlFund = new PayApplyDtlFund();
        //	payApplyDtlFund.setHeadId(id);
        //	payApplyDtlFund.setBilId(arFundVO.getId());
        //	payApplyDtlFundService.insert(payApplyDtlFund);
        //
        //});
        //payApplyVO.setArfundIDList(arfundItemIds);

        //支付申请明细表-奖励单
        List<FeeRewardVO> arfunds = payApplyVO.getArfunds();//其他扣款主表id
        List<Long> feeRewardIdList = new ArrayList<>();
        if (!arfunds.isEmpty()) arfunds.forEach(feeRewardVo -> {
            FeeReward arFund = feeRewardService.selectById(feeRewardVo.getId());
            if (arFund == null) throw new BaseException("指定其他扣款不存在");
            BeanUtils.copyProperties(arFund, feeRewardVo);

			/*
			 获取金额数据
			 */
            BigDecimal sum = feeRewardVo.getRedSum();
            BigDecimal executeSum = feeRewardVo.getPerformSum();// 已执行金额
            BigDecimal balance = feeRewardVo.getBalanceSum(); // 余额
            BigDecimal singleWithHoldSum = feeRewardVo.getSingleWithHoldSum();
			/*
			 验证数据
			 */
            sum = (sum == null ? BigDecimal.ZERO : sum);
            executeSum = (executeSum == null ? BigDecimal.ZERO : executeSum);
            balance = (balance == null ? BigDecimal.ZERO : balance);
            singleWithHoldSum = (singleWithHoldSum == null ? BigDecimal.ZERO : singleWithHoldSum);
            if (balance.compareTo(singleWithHoldSum) < 0) {
                throw new BaseException("指定其他扣款剩余金额不足");
            }
            if (sum.compareTo(executeSum.add(balance)) < 0) {
                throw new BaseException("指定其他扣款已扣金额和剩余金额不符");
            }
            feeRewardVo.setPerformSum(executeSum.add(singleWithHoldSum));
            feeRewardVo.setBalanceSum(balance.subtract(singleWithHoldSum));

            feeRewardIdList.add(feeRewardVo.getId());
            PayApplyDtlFund payApplyDtlFund = new PayApplyDtlFund();
            payApplyDtlFund.setHeadId(id);
            payApplyDtlFund.setBilId(feeRewardVo.getId());
            // 当次补贴金额
            payApplyDtlFund.setArSum(singleWithHoldSum);
            payApplyDtlFundService.insert(payApplyDtlFund);

        });
        payApplyVO.setArfundIDList(feeRewardIdList);

        //支付申请明细表-考核扣款
        List<FeeAssessmentVO> feeAssessmentVOS = payApplyVO.getFeeAssessments();//考核扣款主表id
        List<Long> feeAssessmentItemIds = new ArrayList<>();
        if (!feeAssessmentVOS.isEmpty()) {
            feeAssessmentVOS.forEach(feeAssessmentVO -> {
                FeeAssessment feeAssessment = feeAssessmentService.selectById(feeAssessmentVO.getId());
                if (feeAssessment == null) throw new BaseException("指定考核扣款不存在");
                BeanUtils.copyProperties(feeAssessment, feeAssessmentVO);

				/*
				 获取金额数据
				 */
                BigDecimal amount = feeAssessmentVO.getAmount();
                BigDecimal performSum = feeAssessmentVO.getPerformSum();
                BigDecimal balanceSum = feeAssessmentVO.getBalanceSum();
                BigDecimal singleAssesmentSum = feeAssessmentVO.getSingleAssesmentSum();
				/*
				 验证数据
				 */
                amount = (amount == null ? BigDecimal.ZERO : amount);
                performSum = (performSum == null ? BigDecimal.ZERO : performSum);
                balanceSum = (balanceSum == null ? BigDecimal.ZERO : balanceSum);
                singleAssesmentSum = (singleAssesmentSum == null ? BigDecimal.ZERO : singleAssesmentSum);
                if (balanceSum.compareTo(singleAssesmentSum) < 0) {
                    throw new BaseException("指定考核扣款剩余金额不足");
                }
                if (amount.compareTo(performSum.add(balanceSum)) != 0) {
                    throw new BaseException("指定考核扣款已扣金额和剩余金额不符");
                }
                feeAssessmentVO.setPerformSum(performSum.add(singleAssesmentSum));
                feeAssessmentVO.setBalanceSum(balanceSum.subtract(singleAssesmentSum));

                feeAssessmentItemIds.add(feeAssessmentVO.getId());
                PayApplyDtlAsse payApplyDtlAsse = new PayApplyDtlAsse();
                payApplyDtlAsse.setHeadId(id);
                payApplyDtlAsse.setBilId(feeAssessmentVO.getId());
                // 当次考核
                payApplyDtlAsse.setArSum(feeAssessmentVO.getSingleAssesmentSum());
                payApplyDtlAsseService.insert(payApplyDtlAsse);
            });
        }
        payApplyVO.setFeeAssessmentIDList(feeAssessmentItemIds);

        //支付申请明细表-预付账单
        List<SinglePrepayBill> prepayBillIDList = payApplyVO.getPrepayBills();//预付账单主表id
        List<Long> prepayBillItemIds = new ArrayList<>();
        if (!prepayBillIDList.isEmpty()) {
            prepayBillIDList.forEach(prepayBillID -> {
                PrepayBill prepayBill = prepayBillService.selectById(prepayBillID.getId());
                if (prepayBill == null) throw new BaseException("指定考核扣款不存在");
                BeanUtils.copyProperties(prepayBill, prepayBillID);
                prepayBillItemIds.add(prepayBillID.getId());
                PayApplyDtlPrepay payApplyDtlPrepay = new PayApplyDtlPrepay();
                payApplyDtlPrepay.setHeadId(id);
                payApplyDtlPrepay.setBilId(prepayBillID.getId());
                payApplyDtlPrepayService.insert(payApplyDtlPrepay);
            });
        }
        payApplyVO.setPrepayBillIDList(prepayBillItemIds);
    }

    private void calculationPayMoney(PayApplyVO payApplyVO) {
        //均摊总金额
        BigDecimal deuceCountSum = new BigDecimal(BigDecimal.ROUND_UP);
        //账单主表id
        List<Long> billIDList = payApplyVO.getBillIDList();
        //其他扣款主表id
        List<Long> arfundIDList = payApplyVO.getArfundIDList();
        //考核奖惩费用id
        List<Long> feeAssessmentIDList = payApplyVO.getFeeAssessmentIDList();

        //汇聚应付账款主表的id
        List<Long> feePayableIdList = Lists.newArrayList();
        //根据多个账单ID,得到账单明细
        List<BillDetail> billDetailList = billDetailService.getBillDetailList(billIDList);
        if (billDetailList.isEmpty()) throw new BaseException("获取账单明细，失败！");
        billDetailList.forEach(billDetail -> {
            //记录应付账款主表的id
            feePayableIdList.add(billDetail.getFeeId());
        });

        //------计算均摊金额 Begin
        //if (!arfundIDList.isEmpty()) {
        //	//根据多个其他扣款id，查询其他扣款列表
        //	List<ArFundVO> arFunList = payApplyVO.getArfunds();
        //	if (arFunList.isEmpty()) throw new BaseException("获取其他扣款列表，失败！");
        //	for (int i = 0; i < arFunList.size(); i++) {
        //		ArFundVO arFund = arFunList.get(i);
        //		//根据【其他扣款】的OTM运单号明细id，和应付账款ID,查询应付账款
        //		List<FeePayable> feePayableList = feePayableService.getFeePayableByWaybillDtlId(arFund.getWaybillDtlId(), feePayableIdList);
        //		//如果其他扣款找不到应付账款，则记录均摊金额
        //		if (ObjectUtils.isEmpty(feePayableList)) {
        //			deuceCountSum = deuceCountSum.add(arFund.getSingleWithHoldSum());
        //		}
        //	}
        //}
        if (!feeAssessmentIDList.isEmpty()) {
            //根据多个【考核奖惩费用】id,获取考核信息
            List<FeeAssessmentVO> feeAssessmentList = payApplyVO.getFeeAssessments();
            if (feeAssessmentList.isEmpty()) throw new BaseException("获取核奖惩列表，失败！");
            for (int i = 0; i < feeAssessmentList.size(); i++) {
                FeeAssessmentVO feeAssessment = feeAssessmentList.get(i);
                //根据【考核奖惩费用】的OTM运单号明细id，和应付账款ID,得到应付账款
                List<FeePayable> feePayableList = feePayableService.getFeePayableByWaybillDtlId(feeAssessment.getWaybillDtlId(), feePayableIdList);
                //如果考核奖惩费用找不到应付账款，则记录均摊金额
                if (ObjectUtils.isEmpty(feePayableList)) {
                    deuceCountSum = deuceCountSum.add(feeAssessment.getSingleAssesmentSum());
                }
            }
        }
        //------计算均摊金额 End

        //------执行应付账款扣款总额 Begin
        //均摊总金额除以应付账款的条数(保留两位小数点)
        BigDecimal deuceTotal = deuceCountSum.divide(new BigDecimal(feePayableIdList.size()), 2, BigDecimal.ROUND_HALF_UP);
        //根据多个账单ID,得到账单明细
        // for (int i = 0; i < feePayableIdList.size(); i++) {
        //     //得到应付账款ID
        //     Long feePayableId = feePayableIdList.get(i);
        //     //根据id得到应付账款
        //     FeePayable feePayable = feePayableService.queryFeePayableById(feePayableId);
        //     if (ObjectUtils.isEmpty(feePayable)) throw new BaseException("获取应付账款，失败！" + feePayableId);
        //     //得到其他扣款金额
        //     BigDecimal feePayableDeductTotal = new BigDecimal(0);
        //     List<Long> arfundIds = arFundService.getFeePayableSumByFeepIdAndIds(feePayableId, arfundIDList);
        //     if (!CollectionUtils.isEmpty(arfundIds)) {
        //         payApplyVO.getArfunds().forEach(arFundVO -> {
        //             if (arfundIds.contains(arFundVO.getId())) {
        //                 feePayableDeductTotal.add(arFundVO.getSingleWithHoldSum());
        //             }
        //         });
        //     }
        //     //得到考核奖惩金额
        //     BigDecimal feeAssessmentDeductTotal = new BigDecimal(0);
        //     List<Long> feeAssessmentIds = feeAssessmentService.getFeeAssessmentSumByFeepIdAndIds(feePayableId, feeAssessmentIDList);
        //     if (!CollectionUtils.isEmpty(feeAssessmentIds)) {
        //         payApplyVO.getFeeAssessments().forEach(feeAssessmentVO -> {
        //             if (feeAssessmentIds.contains(feeAssessmentVO.getId())) {
        //                 feeAssessmentDeductTotal.add(feeAssessmentVO.getSingleAssesmentSum());
        //             }
        //         });
        //     }
        //     //得到其他扣款和考核奖惩的扣款总额
        //     BigDecimal deductTotal = feePayableDeductTotal.add(feeAssessmentDeductTotal);
        //     //得到计算后的应付账款扣款总额
        //     BigDecimal deduct = deductTotal.add(deuceTotal);
        //     //修改应付账款总扣款金额
        //     FeePayable feePayableTemp = new FeePayable();
        //     feePayableTemp.setId(feePayableId);
        //     //如果扣款总额大于结算金额则用结算金额
        //     if (deduct.compareTo(feePayable.getActualAmt()) == 1) {
        //         feePayableTemp.setDeduct(feePayable.getActualAmt());
        //     } else {
        //         feePayableTemp.setDeduct(deduct);
        //     }
        //     feePayableService.updateFeePayable(feePayableTemp);
        // }
        List<FeePayable> selectFeePayableList = feePayableService.selectBatchIds(feePayableIdList);
        if (!CollectionUtils.isEmpty(selectFeePayableList)) {
            List<FeePayable> updateFeePaybleList = Lists.newArrayList();

            selectFeePayableList.forEach(feePayable -> {
                //得到其他扣款金额
                BigDecimal feePayableDeductTotal = new BigDecimal(0);
                if (!CollectionUtils.isEmpty(arfundIDList)) {
                    List<Long> arfundIds = arFundService.getFeePayableSumByFeepIdAndIds(feePayable.getId(), arfundIDList);
                    if (!CollectionUtils.isEmpty(arfundIds)) {
                        payApplyVO.getArfunds().forEach(arFundVO -> {
                            if (arfundIds.contains(arFundVO.getId())) {
                                feePayableDeductTotal.add(arFundVO.getSingleWithHoldSum());
                            }
                        });
                    }
                }
                //得到考核奖惩金额
                BigDecimal feeAssessmentDeductTotal = new BigDecimal(0);
                if (!CollectionUtils.isEmpty(feeAssessmentIDList)) {
                    List<Long> feeAssessmentIds = feeAssessmentService.getFeeAssessmentSumByFeepIdAndIds(feePayable.getId(), feeAssessmentIDList);
                    if (!CollectionUtils.isEmpty(feeAssessmentIds)) {
                        payApplyVO.getFeeAssessments().forEach(feeAssessmentVO -> {
                            if (feeAssessmentIds.contains(feeAssessmentVO.getId())) {
                                feeAssessmentDeductTotal.add(feeAssessmentVO.getSingleAssesmentSum());
                            }
                        });
                    }
                }
                //得到其他扣款和考核奖惩的扣款总额
                BigDecimal deductTotal = feePayableDeductTotal.add(feeAssessmentDeductTotal);
                //得到计算后的应付账款扣款总额
                BigDecimal deduct = deductTotal.add(deuceTotal);
                //修改应付账款总扣款金额
                FeePayable feePayableTemp = new FeePayable();
                feePayableTemp.setId(feePayable.getId());
                //如果扣款总额大于结算金额则用结算金额
                if (deduct.compareTo(feePayable.getActualAmt()) == 1) {
                    feePayableTemp.setDeduct(feePayable.getActualAmt());
                } else {
                    feePayableTemp.setDeduct(deduct);
                }
                updateFeePaybleList.add(feePayableTemp);
            });
            if (!CollectionUtils.isEmpty(updateFeePaybleList)) {
                feePayableService.updateBatchById(updateFeePaybleList);
            }
        }
        //------执行应付账款扣款总额 End

        //------执行账单扣款总额 Begin
        billIDList.forEach(billID -> {
            //根据账单ID，得到多个应付账款聚合金额
            BigDecimal deductTotal = feePayableService.getFeePayableDeductTotalByBillid(billID);
            if (ObjectUtils.isEmpty(deductTotal)) throw new BaseException("获取应付账款总金额，失败！");
            //修改账单总扣款金额
            billService.updateBillAffirmDeductSum(billID, deductTotal);
        });
        //------执行账单扣款总额 End

        List<FeeAssessment> feeAssessments = new ArrayList<>();
        //List<ArFund> arFunds = new ArrayList<>();
        List<FeeReward> feeRewardList = new ArrayList<>();
        payApplyVO.getFeeAssessments().forEach(feeAssessmentVO -> feeAssessments.add(feeAssessmentVO));
        payApplyVO.getArfunds().forEach(arFundVO -> feeRewardList.add(arFundVO));

        if (!CollectionUtils.isEmpty(feeAssessments)) {
            feeAssessmentService.updateBatchById(feeAssessments);
        }

        if (!CollectionUtils.isEmpty(feeRewardList)) {
            //arFundService.updateBatchById(feeRewardList);
            feeRewardService.updateBatchById(feeRewardList);
        }
    }

    @Override
    public PayApplyObjVO getPayApplyByPayIdList(long payId) {
//        // 支付申请明细表-考核扣款
//        List<PayApplyDtlAsse> payApplyDtlAssesList = payApplyDtlAsseService.queryPayApplyDtlAsseList(payId);
//        List<Long> asseIDs = Lists.newArrayList();
//        payApplyDtlAssesList.forEach(payApplyDtlAsse -> {
//            asseIDs.add(payApplyDtlAsse.getBilId());
//        });
//        //支付申请明细表-账单
//        List<PayApplyDtlBill> payApplyDtlBillsList = payApplyDtlBillService.queryPayApplyDtlBillList(payId);
//        List<Long> billIDs = Lists.newArrayList();
//        payApplyDtlBillsList.forEach(payApplyDtlBills -> {
//            billIDs.add(payApplyDtlBills.getBilId());
//        });
//        // 支付申请明细表-其他扣款
//        List<PayApplyDtlFund> payApplyDtlFundsList = payApplyDtlFundService.queryPayApplyDtlFundList(payId);
//        List<Long> fundIDs = Lists.newArrayList();
//        payApplyDtlFundsList.forEach(payApplyDtlFunds -> {
//            fundIDs.add(payApplyDtlFunds.getBilId());
//        });
//        // 支付申请明细表-预付账单
//        List<PayApplyDtlPrepay> payApplyDtlPrepaysList = payApplyDtlPrepayService.queryPayApplyDtlPrepayList(payId);
//        List<Long> prepayIDs = Lists.newArrayList();
//        payApplyDtlPrepaysList.forEach(payApplyDtlPrepays -> {
//            prepayIDs.add(payApplyDtlPrepays.getBilId());
//        });


        // 其他扣款
        //List<ArFund> arFundLineByPayList = arFundService.getArFundLineByPayIdList(payId);
        List<FeeRewardVO> feeRewardList = feeRewardService.getFeeRewardVOListByPayId(payId);
        // 账单
        List<Bill> billList = billService.queryBillPurchaseList(payId);
        // 预付账单
        List<PrepayBill> payApplyByPayIDList = prepayBillService.getPayApplyByPayIDList(payId);
        // 考核奖惩
        List<FeeAssessmentVO> feeAssessmentByPayIdList = feeAssessmentService.getFeeAssessmentVoListByPayId(payId);

        PayApplyObjVO payApplyObjVO = new PayApplyObjVO();

        HashMap<String, Object> map = Maps.newHashMap();
        map.put("id", payId);
        List<PayApply> payApplies = this.queryPayApplyList(map);
        if (payApplies.isEmpty()) return null;

        PayApply payApply = payApplies.get(0);
        BeanUtils.copyProperties(payApply, payApplyObjVO);

        payApplyObjVO.setBillList((billList == null ? new ArrayList<>() : billList));
        payApplyObjVO.setFeeAssessmentList((feeAssessmentByPayIdList == null ? new ArrayList<>() : feeAssessmentByPayIdList));
        //payApplyObjVO.setFeeReceivableList((arFundLineByPayList == null ? new ArrayList<>() : arFundLineByPayList));
        payApplyObjVO.setFeeReceivableList((feeRewardList == null ? new ArrayList<>() : feeRewardList));
        payApplyObjVO.setPrepayBillList((payApplyByPayIDList == null ? new ArrayList<>() : payApplyByPayIDList));

        return payApplyObjVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void verifyPayApply(List<Long> payIds) {
        if (!CollectionUtils.isEmpty(payIds)) {
            Boolean invoiceCheck = this.isInvoiceCheck(payIds);
            if (invoiceCheck) throw new BaseException("审核失败，检测到有支付申请单已开票！");

            EntityWrapper<PayApply> ew = new EntityWrapper();
            ew.in("id", payIds);

            PayApply payApply = new PayApply();
            payApply.setStatus(1);//账单状态 0-新增 1-审核
            this.update(payApply, ew);
        }
    }

    /**
     * 支付申请提交审核
     *
     * @param payIds
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void commitConfirmPayApply(List<Long> payIds) {
        try {

            if (!CollectionUtils.isEmpty(payIds)) {
                Boolean invoiceCheck = this.isInvoiceCheck(payIds);
                if (invoiceCheck) {
                    throw new BaseException("提交审核失败，检测到有支付申请单已开票！");
                }
                String pId = null;
                Task task = null;
                JwtAccountVO account = AccountUtil.getAccountInfoFromSecurityContext();
                for (Long payId : payIds) {
                    PayApply payApply = new PayApply();
                    payApply.setId(payId);
                    payApply.setStatus(2);//账单状态 0-新增 1-审核, 2-审核中

                    // 判断车队类型
                    Map<String, Object> payApplyStartFlowType = getPayApplyStartFlowType(payId);
                    if (payApplyStartFlowType == null) {
                        throw new BaseException("无法判断车队类型, 不可提交审核");
                    }
                    // 开启审批流程
                    pId = activitiCommonService.startPayApplyWorkFlow(payApplyStartFlowType);
                    payApply.setActivitiProcessId(pId);
                    if (!StringUtils.isEmpty(pId)) {
                        // 获取
                        task = activitiCommonService.getCurrentTaskByProcessId(pId);
                        if (task != null) {
                            payApply.setActivitiTaskId(task.getId());
                            payApply.setActivitiTaskAssignee(task.getAssignee());
                            payApply.setActivitiTaskName(String.format(ActivitiEnum.ASSIGNEE_FORM, task.getName()));
                        }
                    }
                    if (account != null && !StringUtils.isEmpty(account.getAccountId())) {
                        payApply.setConfirmUser(account.getAccountId());
                    }
                    updateById(payApply);
                    // 2019-05-29 更新应付账单的信息
                    updateFeePayable(payApply.getId(), new Date());
                    pId = null;
                    task = null;
                }
            }
        } catch (Exception e) {
            throw new BaseException("提交审核失败");
        }
    }

    /**
     * 支付申请审核车队类型判断
     *
     * @param id
     * @return
     */
    private Map<String, Object> getPayApplyStartFlowType(Long id) {
        if (id != null) {
            PayApply payApply = selectById(id);
            if (payApply != null && payApply.getLspId() != null) {
                LspFleetDTO fleetInfo = lspUtil.getFleetInfo(Long.parseLong(payApply.getLspId()));
                if (fleetInfo != null && FleetAttributeEnum.OFFICIAL_ATTRIBUTE.getCode().equals(fleetInfo.getFleetAttribute())) {
                    // 正式车队
                    Map<String, Object> map = Maps.newHashMap();
                    map.put(ActivitiEnum.PAY_APPLY_START_FLEET_TYPE.getCode(), FleetAttributeEnum.OFFICIAL_ATTRIBUTE.getCode());
                    return map;
                } else {
                    // 临时车队
                    Map<String, Object> map = Maps.newHashMap();
                    map.put(ActivitiEnum.PAY_APPLY_START_FLEET_TYPE.getCode(), FleetAttributeEnum.TEMP_ATTRIBUTE.getCode());
                    return map;
                }
            }
        }
        return null;
    }

    /**
     * 支付申请单的取消审核
     *
     * @param payIds
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void cancelVerifyPayApply(List<Long> payIds) {
        try {
            Boolean invoiceCheck = this.isInvoiceCheck(payIds);
            if (invoiceCheck) throw new BaseException("取消审核失败，检测到有支付申请单已开票！");

            // EntityWrapper<PayApply> ew = new EntityWrapper();
            // ew.in("id", payIds);
            //
            // PayApply payApply = new PayApply();
            // payApply.setStatus(0);//账单状态 0-新增 1-审核
            // this.update(payApply, ew);
            // 校验
            // 取消审核需要从审批流中剔除
            List<PayApply> payApplyList = selectBatchIds(payIds);
            List<String> pidList = Lists.newArrayList();

            List<FeePayable> updateFeePayableList = Lists.newArrayList();

            if (!CollectionUtils.isEmpty(payApplyList)) {
                for (PayApply payApply : payApplyList) {
                    JwtAccountVO account = AccountUtil.getAccountInfoFromSecurityContext();
                    // 校验
                    if (account == null || StringUtils.isEmpty(account.getUsername())) {
                        throw new BaseException("获取不到当前登录用户, 请重新登录!");
                    } else {
                        if (!StringUtils.isEmpty(payApply.getActivitiTaskAssignee())
                                || !StringUtils.isEmpty(payApply.getConfirmUser())) {
                            if (!payApply.getActivitiTaskAssignee().contains(account.getUsername())
                                    && !payApply.getConfirmUser().contains(account.getAccountId())) {
                                throw new BaseException("当前登录用户没有取消当前节点的权限!");
                            }
                        }
                    }
                }

                payApplyList.forEach(payApply -> {
                    if (org.apache.commons.lang3.StringUtils.isNotBlank(payApply.getActivitiProcessId())) {
                        pidList.add(payApply.getActivitiProcessId());
                    }
                    payApply.setStatus(0);//账单状态 0-新增 1-审核
                    payApply.setActivitiTaskAssignee(null);
                    payApply.setActivitiTaskName(null);
                    payApply.setActivitiTaskId(null);
                    payApply.setActivitiProcessId(null);
                    // 2019-05-29 回退应付账款的支付申请的状态
                    List<FeePayable> feePayableList = getFeePayableListById(payApply.getId());
                    if (!CollectionUtils.isEmpty(feePayableList)) {
                        updateFeePayableList.addAll(feePayableList);
                    }
                });
                // 删除审批流
                if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(pidList)) {
                    for (String pid : pidList) {
                        activitiCommonService.deleteActivitiByProcessId(pid, "取消审核");
                    }
                }
            }
            // 更新
            if (!CollectionUtils.isEmpty(payApplyList)) {
                updateAllColumnBatchById(payApplyList);
            }
            // 更新应付账款的支付申请标识
            if (!CollectionUtils.isEmpty(updateFeePayableList)) {
                callBackFeePayableFlag(updateFeePayableList);
            }
        } catch (BaseException e) {
            throw new BaseException(e.getMessage());
        } catch (Exception e) {
            throw new BaseException("取消审核失败");
        }
    }

    /**
     * 校验是否开票
     *
     * @param payIds
     * @return
     */
    private Boolean isInvoiceCheck(List<Long> payIds) {
        AtomicReference<Boolean> isInvoice = new AtomicReference<>(false);
        EntityWrapper<PayApply> ew = new EntityWrapper();
        ew.in("id", payIds);
        List<PayApply> payApplyList = this.selectList(ew);
        if (payApplyList.isEmpty()) return isInvoice.get();
        payApplyList.forEach(payApply -> {
            //是否开票 0-否, 1-是
            if (Objects.deepEquals(1, payApply.getIsInvoice())) {
                isInvoice.set(true);
                return;
            }
        });
        return isInvoice.get();
    }

    @Override
    public CommonVO<PayApplyCapitalVO> selectPayApplyListByAllMoney(Map<String, Object> condition) {
        CommonVO<PayApplyCapitalVO> payApplies = new CommonVO<PayApplyCapitalVO>();
        List<PayApplyCapitalVO> payApplyCapitalVOS = new ArrayList<>();
        EntityWrapper<PayApply> payApplyEntityWrapper = new EntityWrapper<>();

        BigDecimal billSum;
        if (condition.get("billSum") == null) {
            billSum = new BigDecimal("0");
        } else {
            billSum = new BigDecimal(condition.get("billSum").toString());
        }
        BigDecimal oilBaPaySum;
        if (condition.get("oilBaPaySum") == null) {
            oilBaPaySum = new BigDecimal("0");
        } else {
            oilBaPaySum = new BigDecimal(condition.get("oilBaPaySum").toString());
        }
        BigDecimal cashBaPaySum;
        if (condition.get("cashBaPaySum") == null) {
            cashBaPaySum = new BigDecimal("0");
        } else {
            cashBaPaySum = new BigDecimal(condition.get("cashBaPaySum").toString());
        }

        int pageCurrent = 1;
        if (condition.get("pageCurrent") != null && !"".equals(condition.get("pageCurrent")))
            pageCurrent = Integer.valueOf(condition.get("pageCurrent").toString());

        BigDecimal money = new BigDecimal(condition.get("allMoney").toString()).setScale(2, BigDecimal.ROUND_HALF_UP);
        if (Objects.isNull(money)) throw new BaseException("请输入分配的金额");
        //存有剩余预付金额的列
        if (condition.get("nInId") != null && !"".equals(condition.get("nInId"))) {
            payApplyEntityWrapper.notIn("id", JSONArray.parseArray(condition.get("nInId").toString()));
        }
        if (condition.get("inId") != null && !"".equals(condition.get("inId"))) {
            payApplyEntityWrapper.in("id", JSONArray.parseArray(condition.get("inId").toString()));
        }
        Object status = condition.get("status");
        if (!StringUtils.isEmpty(status)) {
            payApplyEntityWrapper.eq("status", status);
        }
        if (!StringUtils.isEmpty(condition.get("noFllExamine"))) {
            payApplyEntityWrapper.andNew().isNotNull("no_execute_sum").ne("no_execute_sum", BigDecimal.ZERO);
        }
        payApplyEntityWrapper.gt("no_execute_sum", 0);
        payApplyEntityWrapper.orderBy("should_receipt_date asc,id asc");
        Page<PayApply> payApplyPage = this.selectPage(new Page<>(pageCurrent, 10), payApplyEntityWrapper);
        //分配金额
        for (PayApply payApply :
                payApplyPage.getRecords()) {
            PayApplyCapitalVO payApplyCapitalVO = new PayApplyCapitalVO();
            BeanUtils.copyProperties(payApply, payApplyCapitalVO);
            if (payApplyCapitalVO.getExecuteSum() == null) {
                payApplyCapitalVO.setExecuteSum(BigDecimal.ZERO);
            }
            if (payApplyCapitalVO.getNoExecuteSum() == null) {
                payApplyCapitalVO.setNoExecuteSum(BigDecimal.ZERO);
            }
            payApplyCapitalVO.setOldExecuteSum(payApplyCapitalVO.getExecuteSum());
            payApplyCapitalVO.setOldNoExecuteSum(payApplyCapitalVO.getNoExecuteSum());
            payApplyCapitalVO.setOldOilAlPaySum(payApplyCapitalVO.getOilAlPaySum());
            payApplyCapitalVO.setOldOilErPaySum(payApplyCapitalVO.getOilErPaySum());
            payApplyCapitalVO.setOldCashAlPaySum(payApplyCapitalVO.getCashAlPaySum());
            payApplyCapitalVO.setOldCashErPaySum(payApplyCapitalVO.getCashErPaySum());
            billSum = billSum.add(payApply.getBillSum() == null ? BigDecimal.ZERO : payApply.getBillSum());
            oilBaPaySum = oilBaPaySum.add(payApply.getOilBaPaySum() == null ? BigDecimal.ZERO : payApply.getOilBaPaySum());
            cashBaPaySum = cashBaPaySum.add(payApply.getCashBaPaySum() == null ? BigDecimal.ZERO : payApply.getCashBaPaySum());

            if (money.compareTo(payApplyCapitalVO.getNoExecuteSum()) > 0) {
                /*
                 * 本次分配金额大于所需金额
                 */
                //减少可分配的总金额
                money = money.subtract(payApplyCapitalVO.getNoExecuteSum()).setScale(2, BigDecimal.ROUND_HALF_UP);
                //将所需的排款金额进行排放
                payApplyCapitalVO.setExecuteSum(payApplyCapitalVO.getExecuteSum().add(payApplyCapitalVO.getNoExecuteSum()));
                //本次排款金额为此次排款前剩余的未排款金额
                payApplyCapitalVO.setThisExecuteSum(payApplyCapitalVO.getNoExecuteSum());
                payApplyCapitalVO.setThisNoExecuteSum(BigDecimal.ZERO);
                //修改剩余未排款金额未0元
                payApplyCapitalVO.setNoExecuteSum(BigDecimal.ZERO);
                this.bindPayApplyAllSumTailMoneyProperty(payApplyCapitalVO);

                payApplyCapitalVOS.add(payApplyCapitalVO);
            } else {
                /*
                 * 本次分配金额不足已分配该次排款
                 */
                //将可用金额进行排款设置
                payApplyCapitalVO.setNoExecuteSum(payApplyCapitalVO.getNoExecuteSum().subtract(money));
                //本次排款金额为本次分配的金额
                payApplyCapitalVO.setThisExecuteSum(money);
                //本次未排款金额为剩余未排款金额
                payApplyCapitalVO.setThisNoExecuteSum(payApplyCapitalVO.getNoExecuteSum());
                //修改已经排款的金额为之前排款的金额加上此次排款的金额
                payApplyCapitalVO.setExecuteSum(payApplyCapitalVO.getExecuteSum().add(money));
                this.bindPayApplyAllSumTailMoneyProperty(payApplyCapitalVO);

                payApplyCapitalVOS.add(payApplyCapitalVO);
                money = BigDecimal.ZERO;
                break;
            }
        }
        condition.put("allMoney", String.valueOf(money));
        condition.put("billSum", billSum);
        condition.put("oilBaPaySum", oilBaPaySum);
        condition.put("cashBaPaySum", cashBaPaySum);
        //存有剩余金额
        if (money.compareTo(BigDecimal.ZERO) == 1) {
            //可以匹配的总数据可以进行下次分页
            if (payApplyPage.getPages() > payApplyPage.getCurrent()) {
                //修找下一页数据
                condition.put("pageCurrent", String.valueOf(pageCurrent + 1));
                //使用剩余金额进行下页的检索
                CommonVO<PayApplyCapitalVO> payApplyCommonVO = this.selectPayApplyListByAllMoney(condition);
                List<PayApplyCapitalVO> payApplies1 = payApplyCommonVO.getEntityParams();
                payApplies1.forEach(payApply -> payApplyCapitalVOS.add(payApply));
            }
        }
        condition.put("remainderSum", billSum.subtract(oilBaPaySum));
        payApplies.setEntityParams(payApplyCapitalVOS);
        payApplies.setCondition(condition);
        return payApplies;
    }

    private void bindPayApplyAllSumTailMoneyProperty(PayApplyCapitalVO payApplyCapitalVO) {
        BigDecimal thisExecuteSum = payApplyCapitalVO.getThisExecuteSum();
        //获取对半金额（/2）并且保留两位小数
        BigDecimal thisPaySumOilMoney = thisExecuteSum.divide(new BigDecimal(2), 2, BigDecimal.ROUND_HALF_UP);
        BigDecimal thisPaySumCashMoney = thisExecuteSum.subtract(thisPaySumOilMoney);
        if (payApplyCapitalVO.getOilErPaySum().compareTo(thisPaySumOilMoney) > 0) {
            if (thisPaySumCashMoney.compareTo(payApplyCapitalVO.getCashErPaySum()) > 0) {
                thisPaySumCashMoney = payApplyCapitalVO.getCashErPaySum();
                thisPaySumOilMoney = thisExecuteSum.subtract(thisPaySumCashMoney);
            }
        } else {
            thisPaySumOilMoney = payApplyCapitalVO.getOilErPaySum();
            thisPaySumCashMoney = thisExecuteSum.subtract(thisPaySumOilMoney);
        }

        if (payApplyCapitalVO.getOilErPaySum().compareTo(thisPaySumOilMoney) > 0) {
            payApplyCapitalVO.setOilErPaySum(payApplyCapitalVO.getOilErPaySum().subtract(thisPaySumOilMoney));
            payApplyCapitalVO.setOilAlPaySum(payApplyCapitalVO.getOilAlPaySum().add(thisPaySumOilMoney));

            payApplyCapitalVO.setThisOilExecutePaySum(thisPaySumOilMoney);
            payApplyCapitalVO.setThisOilNoExecutePaySum(payApplyCapitalVO.getOilAlPaySum());
        } else {
            payApplyCapitalVO.setOilAlPaySum(payApplyCapitalVO.getOilAlPaySum().add(payApplyCapitalVO.getOilErPaySum()));
            payApplyCapitalVO.setThisOilExecutePaySum(payApplyCapitalVO.getOilErPaySum());
            payApplyCapitalVO.setThisOilNoExecutePaySum(payApplyCapitalVO.getOilAlPaySum());
            payApplyCapitalVO.setOilErPaySum(BigDecimal.ZERO);
        }
        if (payApplyCapitalVO.getCashErPaySum().compareTo(thisPaySumCashMoney) > 0) {
            payApplyCapitalVO.setCashErPaySum(payApplyCapitalVO.getCashErPaySum().subtract(thisPaySumCashMoney));
            payApplyCapitalVO.setCashAlPaySum(payApplyCapitalVO.getCashAlPaySum().add(thisPaySumCashMoney));

            payApplyCapitalVO.setThisCashExecutePaySum(thisPaySumCashMoney);
            payApplyCapitalVO.setThisCashNoExecutePaySum(payApplyCapitalVO.getCashAlPaySum());
        } else {
            payApplyCapitalVO.setCashAlPaySum(payApplyCapitalVO.getCashAlPaySum().add(payApplyCapitalVO.getCashErPaySum()));
            payApplyCapitalVO.setThisCashExecutePaySum(payApplyCapitalVO.getCashErPaySum());
            payApplyCapitalVO.setThisCashNoExecutePaySum(payApplyCapitalVO.getCashAlPaySum());
            payApplyCapitalVO.setCashErPaySum(BigDecimal.ZERO);
        }

    }


    /**
     * 根据id获取对应的账单明细
     *
     * @param id
     * @return
     */
    @Override
    public List<Long> getPayApplyBillDetailIdList(Long id) {
        LOGGER.info("PayApplyServiceImpl.getPayApplyBillDetailIdList id: {}", id);
        if (id != null) {
            List<Long> billIdList = Lists.newArrayList();
            EntityWrapper<PayApplyDtlBill> ew = new EntityWrapper<>();
            ew.eq("head_id", id);
            List<PayApplyDtlBill> dtlBillList = payApplyDtlBillService.selectList(ew);
            if (!CollectionUtils.isEmpty(dtlBillList)) {
                dtlBillList.forEach(dtl -> {
                    billIdList.add(dtl.getBilId());
                });
                return billIdList;
            }
        }
        return null;
    }

    /**
     * 根据支付申请单id更新银行卡信息
     *
     * @param payIds
     * @param token
     * @return
     */
    @Override
    public List<PayApply> updateBankDataByPayIds(List<Long> payIds, String token) {
        List<PayApply> payApplies = this.selectBatchIds(payIds);
        List<PayApply> updatePayApplies = new ArrayList<>();
        List<String> fleetIds = new ArrayList<>();
        if (CollectionUtils.isEmpty(payApplies)) throw new BaseException("无匹配支付申请单");
        payApplies.forEach(payApply -> {
            if (Objects.deepEquals(payApply.getBillType(), new Long(20))) {
                String lspId = payApply.getLspId();
                if (lspId != null) {
                    fleetIds.add(lspId);
                }
            } else {
                throw new BaseException(Strings.nullToEmpty(payApply.getPayApplyCode()) + "：不是车队支付申请单");
            }
        });
        List<LspBackFleetDTO> backFleetDTOS = lspUtil.getFleetById(fleetIds, token);
        if (!CollectionUtils.isEmpty(backFleetDTOS)) {
            Map<String, LspBackFleetDTO> backFleetDTOMap = new HashMap<>();
            backFleetDTOS.forEach(lspBackFleetDTO -> backFleetDTOMap.put(lspBackFleetDTO.getId(), lspBackFleetDTO));

            payApplies.forEach(payApply -> {
                LspBackFleetDTO lspBackFleetDTO = backFleetDTOMap.get(payApply.getLspId());
                if (Objects.nonNull(lspBackFleetDTO)) {
                    payApply.setBankCode(lspBackFleetDTO.getBankAccount());
                    payApply.setBankName(lspBackFleetDTO.getBankName());
                    updatePayApplies.add(payApply);
                }
            });
            boolean b = this.updateBatchById(updatePayApplies);
        }
        return updatePayApplies;
    }

    /**
     * 支付申请单审核通过
     *
     * @param payApplyId
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void computePayApplyTask(Long payApplyId) throws Exception {
        LOGGER.info("PayApplyServiceImpl.computePayApplyTask payApplyId: {} ", payApplyId);
        if (payApplyId != null) {
            PayApply payApply = selectById(payApplyId);
            if (payApply != null && org.apache.commons.lang3.StringUtils.isNotBlank(payApply.getActivitiTaskId())) {
                // 校验审批权限
                checkPayApplyPermiss(payApply);
                Task currentTask = activitiCommonService.getCurrentTaskByProcessId(payApply.getActivitiProcessId());
                if (currentTask != null && org.apache.commons.lang3.StringUtils.isNotBlank(currentTask.getAssignee())) {
                    if (ActivitiEnum.JIESUAN_OR_MENGFANJIAO_MFJ_ZF.getCode().equals(currentTask.getAssignee())) {
                        // JIESUAN_OR_MENGFANJIAO_ZF
                        // Map<String, Object> map = Maps.newHashMap();
                        // map.put(ActivitiEnum.JIESUAN_CONDITION.getCode(), ActivitiEnum.JIESUAN_CONDITION_TYPE_2.getCode());
                        Map<String, Object> map = getJiesuanCondition();
                        // 完成下一个节点
                        completeNextTask(map, payApply.getActivitiTaskId(), payApply.getActivitiProcessId());
                    } else if (ActivitiEnum.WYL_OR_XW_OR_ZF.getCode().equals(currentTask.getAssignee())) {
                        // JIESUAN_OR_MENGFANJIAO_ZF
                        // Map<String, Object> map = Maps.newHashMap();
                        // map.put(ActivitiEnum.CAIWU_CONDITION.getCode(), ActivitiEnum.CAIWU_CONDITION_TYPE_1.getCode());
                        Map<String, Object> map = getCaiwuCondition();
                        // 完成下一个节点
                        completeNextTask(map, payApply.getActivitiTaskId(), payApply.getActivitiProcessId());
                    } else if (ActivitiEnum.PAY_APPLY_TASK_ID_XUWEI.getCode().equals(currentTask.getAssignee())
                            || ActivitiEnum.PAY_APPLY_TASK_ID_YANGFANG.getCode().equals(currentTask.getAssignee())) {
                        // 判断车队属性
                        LspFleetDTO fleetInfo = lspUtil.getFleetInfo(Long.parseLong(payApply.getLspId()));
                        if (fleetInfo != null && FleetAttributeEnum.OFFICIAL_ATTRIBUTE.getCode().equals(fleetInfo.getFleetAttribute())) {
                            Map<String, Object> map = Maps.newHashMap();
                            map.put(ActivitiEnum.PAY_APPLY_FLLET_CONDITION.getCode(), FleetAttributeEnum.OFFICIAL_ATTRIBUTE.getCode());
                            activitiCommonService.taskComplete(currentTask.getId(), map);
                        } else {
                            Map<String, Object> map = Maps.newHashMap();
                            map.put(ActivitiEnum.PAY_APPLY_FLLET_CONDITION.getCode(), FleetAttributeEnum.TEMP_ATTRIBUTE.getCode());
                            activitiCommonService.taskComplete(currentTask.getId(), map);
                        }
                    } else {
                        activitiCommonService.taskComplete(currentTask.getId());
                    }
                    // 更新状态和审批信息
                    updateStatus(payApply);
                }
            }
        }
    }

    /**
     * 校验支付申请单的审批权限
     *
     * @param payApply
     */
    private void checkPayApplyPermiss(PayApply payApply) {
        JwtAccountVO account = AccountUtil.getAccountInfoFromSecurityContext();
        // 校验
        if (account == null || StringUtils.isEmpty(account.getUsername())) {
            throw new BaseException("获取不到当前登录用户, 请重新登录!");
        } else {
            if (!StringUtils.isEmpty(payApply.getActivitiTaskAssignee())) {
                if (!payApply.getActivitiTaskAssignee().contains(account.getUsername())) {
                    throw new BaseException("当前登录用户没有审批当前节点的权限!");
                }
            }
        }
    }

    /**
     * 返回结算的判断
     *
     * @return
     */
    private Map<String, Object> getJiesuanCondition() {
        JwtAccountVO account = AccountUtil.getAccountInfoFromSecurityContext();
        Map<String, Object> map = Maps.newHashMap();
        if (account != null && !StringUtils.isEmpty(account.getUsername())) {
            String username = account.getUsername();
            if (ActivitiEnum.JIESUAN_MENTFJ.getCode().equals(username)) {
                map.put(ActivitiEnum.JIESUAN_CONDITION.getCode(), ActivitiEnum.JIESUAN_CONDITION_TYPE_1.getCode());
            } else {
                map.put(ActivitiEnum.JIESUAN_CONDITION.getCode(), ActivitiEnum.JIESUAN_CONDITION_TYPE_2.getCode());
            }
        } else {
            map.put(ActivitiEnum.JIESUAN_CONDITION.getCode(), ActivitiEnum.JIESUAN_CONDITION_TYPE_2.getCode());
        }
        return map;
    }

    /**
     * 获取财务的判断
     *
     * @return
     */
    private Map<String, Object> getCaiwuCondition() {
        JwtAccountVO account = AccountUtil.getAccountInfoFromSecurityContext();
        Map<String, Object> map = Maps.newHashMap();
        if (account != null && !StringUtils.isEmpty(account.getUsername())) {
            String username = account.getUsername();
            if (ActivitiEnum.CAIWU_WANYL.getCode().equals(username)) {
                map.put(ActivitiEnum.CAIWU_CONDITION.getCode(), ActivitiEnum.CAIWU_CONDITION_TYPE_1.getCode());
            } else if (ActivitiEnum.CAIWU_XUWEI.getCode().equals(username)) {
                map.put(ActivitiEnum.CAIWU_CONDITION.getCode(), ActivitiEnum.CAIWU_CONDITION_TYPE_2.getCode());
            } else if (ActivitiEnum.CAIWU_YANGTING.getCode().equals(username)) {
                map.put(ActivitiEnum.CAIWU_CONDITION.getCode(), ActivitiEnum.CAIWU_CONDITION_TYPE_3.getCode());
            } else {
                map.put(ActivitiEnum.CAIWU_CONDITION.getCode(), ActivitiEnum.CAIWU_CONDITION_TYPE_1.getCode());
            }
        } else {
            map.put(ActivitiEnum.CAIWU_CONDITION.getCode(), ActivitiEnum.CAIWU_CONDITION_TYPE_1.getCode());
        }
        return map;
    }

    /**
     * 获取支付申请审批历史
     *
     * @param payApplyId
     * @return
     * @throws Exception
     */
    @Override
    public List<HistoryTask> queryPayApplyHistoryTaskList(Long payApplyId) throws Exception {
        if (payApplyId != null) {
            PayApply payApply = selectById(payApplyId);
            if (payApply != null && org.apache.commons.lang3.StringUtils.isNotBlank(payApply.getActivitiProcessId())) {
                List<HistoryTask> historyTaskList = activitiCommonService.queryActivitiHistoryTaskList(payApply.getActivitiProcessId());
                if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(historyTaskList)) {
                    Iterator<HistoryTask> iterator = historyTaskList.iterator();
                    while (iterator.hasNext()) {
                        HistoryTask next = iterator.next();
                        // 对于中间状态的判断
                        if ((ActivitiEnum.MFJ_OR_ZF_TASK_ID.getCode().equals(next.getActivityId()) && iterator.hasNext())
                                || (ActivitiEnum.WYL_OR_LYT_OR_ZF_TASK_ID.getCode().equals(next.getActivityId()) && iterator.hasNext())
                                || (ActivitiEnum.WYL_OR_XW_OR_ZF_TASK_ID.getCode().equals(next.getActivityId()) && iterator.hasNext())) {
                            iterator.remove();
                        }
                    }
                }
                return historyTaskList;
            }
        }
        return null;
    }

    /**
     * 查询支付申请列表
     *
     * @param page
     * @return
     */
    @Override
    public Page<PayApply> queryWaitConfirmPayApplyPage(Page<PayApply> page) {
        Map<String, Object> condition = page.getCondition();
        EntityWrapper<PayApply> ew = this.queryCheck(condition);
        // if (condition != null) {
        // 	ew.andNew();
        // 	if (condition.get(ActivitiEnum.CURRENT_USER_ID) != null) {
        // 		ew.eq("confirm_user", condition.get(ActivitiEnum.CURRENT_USER_ID));
        // 	}
        // 	if (condition.get(ActivitiEnum.CURRENT_USER_NAME) != null) {
        // 		ew.or();
        // 		ew.eq("activiti_task_assignee", condition.get(ActivitiEnum.CURRENT_USER_NAME));
        // 	}
        // }
        if (condition != null) {
            if ("10".equals(condition.get("confirmTask"))) {
                if (condition.get(ActivitiEnum.CURRENT_USER_ID) != null) {
                    ew.eq("confirm_user", condition.get(ActivitiEnum.CURRENT_USER_ID));
                }
            }
            if ("20".equals(condition.get("confirmTask"))) {
                if (condition.get(ActivitiEnum.CURRENT_USER_NAME) != null) {
                    ew.like("activiti_task_assignee", condition.get(ActivitiEnum.CURRENT_USER_NAME).toString());
                }
            }
        }
        page.setRecords(baseMapper.selectPage(page, ew));
        return page;
    }

    /**
     * 更新万金油哦状态
     */
    @Override
    public void updateOidSyncStatus() {
        EntityWrapper<PayApply> ew = new EntityWrapper<>();
        ew.ne("sync_status", 10);
        ew.isNotNull("cost_id");
        List<PayApply> applyList = baseMapper.selectListNoTenant(ew);
        if (!CollectionUtils.isEmpty(applyList)) {
            applyList.stream()
                    .filter(payApply -> !StringUtils.isEmpty(payApply.getCostId()))
                    .forEach(payApply -> {
                        FcPayApplyReturnDTO fcPayApplyReturnDTO = payApiUtil.getPayApplyAudit(payApply.getCostId()).getData();
                        payApply.setSyncStatus(fcPayApplyReturnDTO.getAuditStatusCode());
                    });
            this.updateBatchById(applyList);
        }
    }

    /**
     * 判断当前账单下的明细在原有的支付申请是否创建过
     *
     * @param billId
     */
    @Override
    public void verifyBillAndPayApply(Long billId) {
        EntityWrapper<BillDetail> ew = new EntityWrapper<>();
        ew.eq("bill_id", billId);
        List<BillDetail> billDetailList = billDetailService.selectList(ew);
        if (!CollectionUtils.isEmpty(billDetailList)) {
            List<Long> feeIdList = Lists.newArrayList();
            billDetailList.forEach(billDtl -> {
                feeIdList.add(billDtl.getFeeId());
            });
            EntityWrapper<BillDetail> oldBillDtlEw = new EntityWrapper<>();
            oldBillDtlEw.setSqlSelect("distinct bill_id");
            oldBillDtlEw.ne("bill_id", billId);
            oldBillDtlEw.in("fee_id", feeIdList);
            List<Object> billIdObjList = billDetailService.selectObjs(oldBillDtlEw);
            if (CollectionUtils.isEmpty(billIdObjList)) {
                return;
            }
            List<Long> billIdList = Lists.newArrayList();
            billIdObjList.forEach(billObj -> {
                billIdList.add(Long.valueOf(billObj.toString()));
            });
            List<Bill> billList = billService.selectBatchIds(billIdList);
            if (CollectionUtils.isEmpty(billList)) {
                return;
            }
            List<Long> apBillIdList = Lists.newArrayList();
            billList.stream().filter(bill -> "20".equals(bill.getBillType())).forEach(bill -> {
                apBillIdList.add(bill.getId());
            });
            if (CollectionUtils.isEmpty(apBillIdList)) {
                return;
            }
            EntityWrapper<PayApplyDtlBill> applyBillDtlEw = new EntityWrapper<>();
            applyBillDtlEw.in("bil_id", apBillIdList);
            int count = payApplyDtlBillService.selectCount(applyBillDtlEw);
            if (count > 0) {
                throw new BaseException("当前账单下的明细存在过已经支付的申请的数据, 请核实以后操作");
            }
            // List<FeePayable> feePayableList = feePayableService.selectBatchIds(feeIdList);
        }
    }

    /**
     * 支付申请推送bms自动出账
     *
     * @param payApply
     */
    @Override
    public void payApplyToBmsCreateBill(PayApply payApply) {
        PayApplyToBmsBill payApplyToBmsBill = new PayApplyToBmsBill();

        // 中联公司主体
        // 2019-11-14 主体根据车队是否慧运车判断
        if (org.apache.commons.lang3.StringUtils.isNotBlank(payApply.getLspName()) && payApply.getLspName().contains("慧运车")) {
            payApplyToBmsBill.setUnlcnCompanyId("ULC/ZC.14");
        } else {
            payApplyToBmsBill.setUnlcnCompanyId("ULC/ZC.02");
        }
        // 申请提交人
        payApplyToBmsBill.setYlRequestUser(payApply.getConfirmUser());
        // 支付申请好
        payApplyToBmsBill.setYlRequestId(payApply.getPayApplyCode());
        // 系统运单号
        List<Bill> billList = billService.queryBillPurchaseList(payApply.getId());
        if (CollectionUtils.isEmpty(billList)) {
            return;
        }
        // 承运商
        payApplyToBmsBill.setShipperId(String.valueOf(billList.get(0).getPayerId()));

        List<Long> billIdList = Lists.newArrayList();
        billList.forEach(bill -> {
            billIdList.add(bill.getId());
        });
        List<String> waybillIdList = billService.getBillSysWaybillId(billIdList);
        if (!CollectionUtils.isEmpty(waybillIdList)) {
            // 系统运单
            payApplyToBmsBill.setWaybillIdList(waybillIdList);
            // 运单数量
            payApplyToBmsBill.setWaybillNum(waybillIdList.size());
        } else {
            // 运单数量
            payApplyToBmsBill.setWaybillNum(0);
        }
        // 考核单和奖励单
        List<PayApplyAssess> payApplyAssessList = Lists.newArrayList();
        // 考核单
        List<PayApplyAssess> feeAssessList = getPayApplyFeeAssessList(payApply.getId());
        if (!CollectionUtils.isEmpty(feeAssessList)) {
            payApplyAssessList.addAll(feeAssessList);
        }

        // 奖励单
        List<PayApplyAssess> feeRewardList = getPayApplyFeeRewardList(payApply.getId());
        if (!CollectionUtils.isEmpty(feeRewardList)) {
            payApplyAssessList.addAll(feeRewardList);
        }
        if (!CollectionUtils.isEmpty(payApplyAssessList)) {
            // 考核单-奖励单
            payApplyToBmsBill.setAssessList(payApplyAssessList);
            // 数量
            payApplyToBmsBill.setAssessListNum(payApplyAssessList.size());
            // 总金额
            BigDecimal assessSum = BigDecimal.ZERO;
            for (PayApplyAssess payApplyAssess : payApplyAssessList) {
                assessSum = assessSum.add(payApplyAssess.getLeftMoney());
            }
            payApplyToBmsBill.setAssessMoney(assessSum);
        } else {
            // 数量
            payApplyToBmsBill.setAssessListNum(0);
            // 总金额
            payApplyToBmsBill.setAssessMoney(BigDecimal.ZERO);
        }

        // 推送
        BmsServiceResult bmsServiceResult = otmUtil.payApplyToBmsCreateBill(payApplyToBmsBill);
        if (bmsServiceResult == null) {
            throw new BaseException("推送BMS未响应");
        } else if (!bmsServiceResult.isSuccess()) {
            throw new BaseException("同步BMS：" + bmsServiceResult.getMessage());
        }
    }

    /**
     * 更新支付状态
     *
     * @param payApply
     */
    private void updatePayApplyState(PayApply payApply) {
        // 更新支付状态
        List<PayApplyDtlPrepay> payApplyDtlPrepayList = payApplyDtlPrepayService.queryPayApplyDtlPrepayList(payApply.getId());
        if (!CollectionUtils.isEmpty(payApplyDtlPrepayList)) {
            List<Long> prepaybillIdList = Lists.newArrayList();
            payApplyDtlPrepayList.forEach(payApplyDtlPrepay -> {
                prepaybillIdList.add(payApplyDtlPrepay.getBilId());
            });
            EntityWrapper<PrepayBill> ew = new EntityWrapper<>();
            ew.in("id", prepaybillIdList);
            PrepayBill updatePrepayBill = new PrepayBill();
            updatePrepayBill.setPayState(1);
            prepayBillService.update(updatePrepayBill, ew);
        }
    }

    /**
     * 获取考核单详情
     *
     * @param payApplyId
     * @return
     */
    private List<PayApplyAssess> getPayApplyFeeAssessList(Long payApplyId) {
        // 考核单
        List<PayApplyDtlAsse> payApplyDtlAsseList = payApplyDtlAsseService.queryPayApplyDtlAsseList(payApplyId);
        if (!CollectionUtils.isEmpty(payApplyDtlAsseList)) {
            List<Long> assessIdList = Lists.newArrayList();
            Map<Long, BigDecimal> payApplyAssessMap = Maps.newHashMap();
            payApplyDtlAsseList.forEach(assess -> {
                assessIdList.add(assess.getBilId());
                payApplyAssessMap.put(assess.getBilId(), assess.getArSum());
            });
            List<FeeAssessment> feeAssessmentList = feeAssessmentService.selectBatchIds(assessIdList);
            if (CollectionUtils.isEmpty(feeAssessmentList)) {
                return null;
            }
            List<PayApplyAssess> payApplyAssessList = Lists.newArrayList();
            feeAssessmentList.forEach(feeAssess -> {
                BigDecimal arSum = payApplyAssessMap.get(feeAssess.getId());
                if (Objects.nonNull(arSum) && BigDecimal.ZERO.compareTo(arSum) < 0) {
                    PayApplyAssess payApplyAssess = new PayApplyAssess();
                    payApplyAssess.setAssessCode(feeAssess.getAssessCode());
                    payApplyAssess.setLeftMoney(arSum.negate());
                    payApplyAssessList.add(payApplyAssess);
                }
            });
            return payApplyAssessList;
        }
        return null;
    }

    /**
     * 获取奖励单详情
     *
     * @param payApplyId
     * @return
     */
    private List<PayApplyAssess> getPayApplyFeeRewardList(Long payApplyId) {
        // 奖励单
        List<PayApplyDtlFund> payApplyDtlFundList = payApplyDtlFundService.queryPayApplyDtlFundList(payApplyId);
        if (!CollectionUtils.isEmpty(payApplyDtlFundList)) {
            List<Long> rewardIdList = Lists.newArrayList();
            Map<Long, BigDecimal> payApplyRewardMap = Maps.newHashMap();
            payApplyDtlFundList.forEach(reward -> {
                rewardIdList.add(reward.getBilId());
                payApplyRewardMap.put(reward.getBilId(), reward.getArSum());
            });
            List<FeeReward> feeRewardList = feeRewardService.selectBatchIds(rewardIdList);
            if (CollectionUtils.isEmpty(feeRewardList)) {
                return null;
            }
            List<PayApplyAssess> payApplyRewardList = Lists.newArrayList();
            feeRewardList.forEach(feeReward -> {
                BigDecimal arSum = payApplyRewardMap.get(feeReward.getId());
                if (Objects.nonNull(arSum) && BigDecimal.ZERO.compareTo(arSum) < 0) {
                    PayApplyAssess payApplyAssess = new PayApplyAssess();
                    payApplyAssess.setAssessCode(feeReward.getRedCode());
                    payApplyAssess.setLeftMoney(arSum.plus());
                    payApplyRewardList.add(payApplyAssess);
                }
            });
            return payApplyRewardList;
        }

        return null;
    }

    /**
     * 完成
     *
     * @param map
     * @param taskId
     * @param pId
     * @return
     * @throws Exception
     */
    private Task completeNextTask(Map<String, Object> map, String taskId, String pId) throws Exception {
        // activitiCommonService.taskComplete(payApply.getActivitiTaskId(), map);
        // // 完成下一个节点
        // currentTask = activitiCommonService.getCurrentTaskByProcessId(payApply.getActivitiProcessId());
        // activitiCommonService.taskComplete(payApply.getActivitiTaskId());
        // currentTask = activitiCommonService.getCurrentTaskByProcessId(payApply.getActivitiProcessId());
        // 完成
        activitiCommonService.taskComplete(taskId, map);

        // 完成下一个节点
        Task current = activitiCommonService.getCurrentTaskByProcessId(pId);
        activitiCommonService.taskComplete(current.getId());

        return activitiCommonService.getCurrentTaskByProcessId(pId);
    }

    /**
     * 更新状态
     *
     * @param payApply
     * @throws Exception
     */
    private void updateStatus(PayApply payApply) throws Exception {
        Task currentTask = activitiCommonService.getCurrentTaskByProcessId(payApply.getActivitiProcessId());
        if (currentTask != null) {
            payApply.setActivitiTaskName(String.format(ActivitiEnum.ASSIGNEE_FORM, currentTask.getName()));
            payApply.setActivitiTaskAssignee(currentTask.getAssignee());
            payApply.setActivitiTaskId(currentTask.getId());
        } else {
            // 流程结束
            payApply.setStatus(1);
            payApply.setActivitiTaskName(ActivitiEnum.FINISH_ASSIGNEE);
            payApply.setActivitiTaskAssignee(null);
            payApply.setActivitiTaskId(null);
            // 针对临时运力生成付款确认单
            createPayConfirmByAttribute(payApply);
            // 针对临时运力推送万金油 - 无排款申请
            tempFleetPushOil(payApply);
            // 推送bms自动出账
            this.payApplyToBmsCreateBill(payApply);
            this.updatePayApplyState(payApply);
        }
        updateAllColumnById(payApply);
    }

    /**
     * 针对临时运力推送万金油 - 无排款申请
     *
     * @param payApply
     */
    private void tempFleetPushOil(PayApply payApply) {
        if (payApply != null && payApply.getOilBaPaySum() != null && payApply.getOilBaPaySum().compareTo(BigDecimal.ZERO) > 0) {
            String lspName = null;
            List<PayApplyDtlBill> dtlBillList = payApplyDtlBillService.queryPayApplyDtlBillList(payApply.getId());
            if (!CollectionUtils.isEmpty(dtlBillList)) {
                PayApplyDtlBill payApplyDtlBill = dtlBillList.get(0);
                if (payApplyDtlBill != null && payApplyDtlBill.getBilId() != null) {
                    Bill bill = billService.selectById(payApplyDtlBill.getBilId());
                    if (bill != null && !StringUtils.isEmpty(bill.getPayerName())) {
                        lspName = bill.getPayerName();
                    }
                }

            }
            FcPayApplyDTO fcPayApplyDTO = new FcPayApplyDTO();
            fcPayApplyDTO.setShipmentGid(payApply.getPayApplyCode());
            // 承运商名称
            fcPayApplyDTO.setPaymentSubject(lspName);
            // 承运人 - 车队
            fcPayApplyDTO.setFleetName(payApply.getLspName());
            fcPayApplyDTO.setPayType("2");
            fcPayApplyDTO.setProvider("万金油");
            fcPayApplyDTO.setApplyForMoney(payApply.getOilBaPaySum());
            // fcPayApplyDTO.setPlateNo(payApply.getv);
            String applyNo = payApiUtil.createPayapply(fcPayApplyDTO).getData();
            payApply.setCostId(applyNo);
            payApply.setSyncStatus("0");
        }
    }

    /**
     * 临时运力直接生产付款确认
     *
     * @param payApply
     */
    private void createPayConfirmByAttribute(PayApply payApply) {
        // 临时运力直接生成付款确认
        if (payApply != null && !StringUtils.isEmpty(payApply.getLspName())) {
            if (payApply.getLspName().contains("临时")) {
                JwtAccountVO account = AccountUtil.getAccountInfoFromSecurityContext();
                PayAffirm payAffirm = new PayAffirm();
                if (ObjectUtils.isEmpty(account)) {
                    throw new BaseException("没有登录信息！");
                }
                // 总付款金额 - 取现金尾款金额
                payAffirm.setPaySum(payApply.getCashBaPaySum());
                //
                payAffirm.setTenantId(Long.valueOf(account.getTenantId()));
                payAffirm.setPayCode(codeUtil.getPayAffirmCode().getNextCode(null));
                //状态; 0-新增, 1-已审核
                payAffirm.setStatus(0);
                payAffirm.setGmtCreate(new Date());
                payAffirm.setType(0);
                payAffirmService.insert(payAffirm);

                PayAffirmApply payAffirmApply = new PayAffirmApply();
                payAffirmApply.setHeadId(payAffirm.getId());
                payAffirmApply.setCapitalDtlId(payApply.getId());
                payAffirmApply.setSum(payApply.getPaymentSum());
                payAffirmApply.setNotPaidSum(payAffirmApply.getSum());
                payAffirmApply.setPaidSum(BigDecimal.ZERO);
                if (payApply.getLspId() != null && org.apache.commons.lang3.StringUtils.isNumeric(payApply.getLspId())) {
                    payAffirmApply.setFleetId(Long.parseLong(payApply.getLspId()));
                }
                payAffirmApply.setFleetName(payApply.getLspName());
                payAffirmApply.setPayCode(payApply.getPayApplyCode());
                payAffirmApplyService.insert(payAffirmApply);


                // 更新 - 对应的信息
                payApply.setCashAlPaySum(payApply.getCashBaPaySum());
                payApply.setCashErPaySum(BigDecimal.ZERO);
                payApply.setExecuteSum(payApply.getCashBaPaySum());
                payApply.setNoExecuteSum(BigDecimal.ZERO);
                payApply.setCurrentExecute(payApply.getExecuteSum());
                payApply.setBalance(BigDecimal.ZERO);
            }
        }
    }

    /**
     * 查询条件
     *
     * @param condition 查询字段
     * @return
     */
    private EntityWrapper<PayApply> queryCheck(Map<String, Object> condition) {
        LOGGER.info("PayApplyServiceImpl.queryLikeCheck INFO: params : {} ", condition);
        EntityWrapper<PayApply> ew = new EntityWrapper<>();
        if (!CollectionUtils.isEmpty(condition)) {
            if (condition.get("asc") == null) {
                ew.orderBy("id desc");
            } else {
                if (Objects.deepEquals(0, condition.get("asc"))) ew.orderBy("should_receipt_date asc");
            }
            //遍历条件
            for (Map.Entry<String, Object> entry : condition.entrySet()) {
                if (!Strings.isNullOrEmpty(entry.getKey())) {
                    LOGGER.info("queryCheck enter foreach INFO: key :" + entry.getKey() + ",Value :" + entry.getValue());
                    //申请ID
                    if ("id".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue()))
                        ew.eq("id", entry.getValue());
                    if ("nIds".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue())) {
                        ew.notIn("id", JSONArray.parseArray(condition.get("nIds").toString()));
                    }
                    if ("ids".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue())) {
                        ew.in("id", JSONArray.parseArray(condition.get("ids").toString()));
                    }
                    //申请单号
                    if ("payApplyCode".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue()))
                        ew.eq("pay_apply_code", entry.getValue());
                    //承运人
                    if ("lspName".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue()))
                        ew.like("lsp_name", entry.getValue().toString());
                    //承运人
                    if ("lspId".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue()))
                        ew.eq("lsp_id", entry.getValue());
                    //状态
                    if ("status".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue()))
                        ew.eq("status", entry.getValue());
                    //类型
                    if ("billType".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue()))
                        ew.eq("bill_type", entry.getValue());
                    //申请开始日期
                    if ("beginDate".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue()))
                        ew.ge("apply_date", entry.getValue());
                    //申请结束日期
                    if ("endDate".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue()))
                        ew.le("apply_date", entry.getValue());
                    //过滤未排款金额非空或在等于0
                    if ("noFllExamine".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue())) {
                        ew.andNew().isNotNull("no_execute_sum").ne("no_execute_sum", BigDecimal.ZERO);
                    }
                    // 小于未排款金额
                    if ("lessNoFllExamine".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue())) {
                        ew.le("no_execute_sum", entry.getValue());
                    }
                    // 支付申请号-批量
                    if ("payApplyCodeList".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue())) {
                        String[] payAppylCodeArray = entry.getValue().toString().trim().replace(" ", "").split(",|;|\n");
                        if (payAppylCodeArray != null && payAppylCodeArray.length > 0) {
                            ew.in("pay_apply_code", payAppylCodeArray);
                        }
                    }
                }
            }
        }
        LOGGER.info("queryCheck result INFO: params : {} ", ew.toString());
        return ew;
    }

    /**
     * 更新应付订单是否支付标识和支付申请单号
     *
     * @param payApplyId
     * @param payDate
     */
    private void updateFeePayable(Long payApplyId, Date payDate) {
        // 找到对应的明细
        PayApply payApply = this.selectById(payApplyId);
        List<FeePayable> feePayableList = getFeePayableListById(payApplyId);
        if (!CollectionUtils.isEmpty(feePayableList) && Objects.nonNull(payApply)) {
            feePayableList.forEach(feePayable -> {
                feePayable.setIsPay(FeePayableBaseEnum.YES.getCode());
                feePayable.setPayCode(payApply.getPayApplyCode());
                feePayable.setPayDate(payDate);
                feePayable.setGmtModify(new Date());
            });
            feePayableService.updateBatchById(feePayableList);
        }
    }

    /**
     * 根据支付申请id获取对应的应付账款集合
     *
     * @param payApplyId
     * @return
     */
    private List<FeePayable> getFeePayableListById(Long payApplyId) {
        List<Long> payIdList = Lists.newArrayList();
        payIdList.add(payApplyId);
        return feePayableService.queryFeePayableListByPayApplyIdList(payIdList);
    }

    /**
     * 回退应付账款的支付申请标识和单号
     *
     * @param feePayableList
     */
    private void callBackFeePayableFlag(List<FeePayable> feePayableList) {
        if (!CollectionUtils.isEmpty(feePayableList)) {
            feePayableList.forEach(feePayable -> {
                feePayable.setIsPay(FeePayableBaseEnum.NO.getCode());
                feePayable.setPayCode(null);
                feePayable.setPayDate(null);
                feePayable.setGmtModify(new Date());
            });
            feePayableService.updateAllColumnBatchById(feePayableList);
        }
    }
}
